﻿using System;
using System.Threading.Tasks;
using CSRedis;

namespace ESoft.Redis
{

    public interface IRedisService
    {
        /// <summary>
        /// 获取缓存。
        /// </summary>
        /// <typeparam name="T">缓存类型。</typeparam>
        /// <param name="key">缓存键值。</param>
        /// <returns>获取到的缓存。</returns>
        T Get<T>(string key);

        /// <summary>
        /// 异步获取缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        Task<T> GetAsync<T>(string key);

        /// <summary>
        /// 获取（创建）缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="increatementFunc"></param>
        /// <returns></returns>
        T GetOrCreateAsync<T>(string key, int time, Func<T> increatementFunc);

        /// <summary>
        /// 异步获取（创建）缓存
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="time"></param>
        /// <param name="increatementFunc"></param>
        /// <returns></returns>
        Task<T> GetOrCreateAsync<T>(string key, int time, Func<Task<T>> increatementFunc);

        /// <summary>
        /// 设置缓存。
        /// </summary>
        /// <typeparam name="T">缓存类型。</typeparam>
        /// <param name="key">缓存键值。</param>
        /// <param name="value">要缓存的对象。</param>
        void Set<T>(string key, T value);

        /// <summary>
        /// 设置缓存。
        /// </summary>
        /// <typeparam name="T">缓存类型。</typeparam>
        /// <param name="key">缓存键值。</param>
        /// <param name="value">要缓存的对象。</param>
        /// <param name="expiredTime">过期时间。</param>
        void Set<T>(string key, T value, TimeSpan expiredTime);

        /// <summary>
        /// 移除指定键值的缓存。
        /// </summary>
        /// <param name="key">缓存键值。</param>
        bool Remove(string key);

        /// <summary>
        /// 获取 Hash 表中的缓存。
        /// </summary>
        /// <typeparam name="T">缓存类型。</typeparam>
        /// <param name="key">缓存键值。</param>
        /// <param name="hashField">要获取的 hash 字段。</param>
        /// <returns>获取到的缓存。</returns>
        T GetHash<T>(string key, string hashField);

        /// <summary>
        /// 设置 缓存到 Hash 表。
        /// </summary>
        /// <typeparam name="T">缓存类型。</typeparam>
        /// <param name="key">缓存键值。</param>
        /// <param name="hashField">要设置的 hash 字段。</param>
        /// <param name="hashValue">要设置的 hash 值。</param>
        void SetHash<T>(string key, string hashField, T hashValue);

        /// <summary>
        /// 删除 hash 表中的指定字段的缓存。
        /// </summary>
        /// <param name="key">缓存键值。</param>
        /// <param name="hashField">hash 字段。</param>
        /// <returns>一个布尔值，表示缓存是否删除成功。</returns>
        bool DeleteHash(string key, string hashField);

        /// <summary>
        ///  只有在 key 不存在时设置 key 的值
        /// </summary>
        /// <param name="lockKey"></param>
        /// <param name="value"></param>
        /// <param name="timeoutSpan"></param>
        /// <returns></returns>
        bool SetNx(string lockKey, object value, double timeoutSpan = 0);

        /// <summary>
        /// 订阅
        /// </summary>
        /// <param name="channels"></param>
        void Subscribe(params (string, Action<CSRedisClient.SubscribeMessageEventArgs>)[] channels);
    }
}

